package com.shiyi.design.singleton;

import java.util.concurrent.TimeUnit;

/**
 * 懒汉式-双重检查
 * 只有在使用的时候，才会实例化对象，但是有线程安全的问题
 * 可以考虑在方法上加锁，由于是静态方法，锁的是SingletonDesignModel4.class对象
 * 但是效率不高，每次都要获取锁
 * 我们可以进行优化，减少锁的粒度，但是这次的写法，也会有线程安全的问题
 * 线程1先执行，进入判断后，线程2执行，也进入了判断，然后继续执行，实例化了对象，然后释放锁
 * 线程1执行，也会实例化对象
 *
 * 上述问题，我们可以通过double check进行解决
 *
 * @Author qiu
 * @Date 2021/1/10 23:09
 */
public class SingletonDesignModel6 {

    private static SingletonDesignModel6 INSTANCE = null;

    private SingletonDesignModel6(){};

    public static SingletonDesignModel6 getInstance() {
        if(INSTANCE == null) {
            synchronized(SingletonDesignModel6.class) {
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if(INSTANCE == null) {
                    INSTANCE = new SingletonDesignModel6();
                }
            }
        }
        return INSTANCE;
    }

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(() -> System.out.println(Thread.currentThread().getName() + "----" + SingletonDesignModel6.getInstance().hashCode())).start();
        }
    }
}
